package com.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dao.QuestionDAO;
import com.dao.RewindDAO;
import com.dao.TestDAO;
import com.pojo.QuestionBase;
import com.pojo.Rewind;
import com.pojo.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@SuppressWarnings("all")
@Service
public class QuestionService extends ServiceImpl<QuestionDAO, QuestionBase> {

    @Autowired
    private QuestionDAO questionDAO;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TestDAO testDAO;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private RewindDAO rewindDAO;

    /**
     *  分页查询试题库中的试题
     * @param page   第几条数据
     * @param limit  一页显示几条数据
     * @param m  查询参数
     * @return
     */
    public IPage searchQuestion(int page, int limit, Map m){
        Page p = new Page(page,limit);
        return questionDAO.searchQuestion(p,m);
    }

    /**
     *  学生日常刷题
     * @param questionBase 试题属性
     * @return
     */
    public Map examinationQuestion(String username,String num,Integer chapter){

        // 在缓存中 根据用户账号作为 key , 找到存在redis中的数据
        Object object= redisTemplate.opsForValue().get(username);
        // 查到了,将数据取出,返回
        if(object!=null){
            Map map=(Map)redisTemplate.opsForValue().get(username);
            return map;
        }

        // 缓存中没有数据,从数据库中取出数据,以用户账号为key,存储在缓存中
        Map map=new HashMap();
        // 每个试题类型的题目数量( 以 ，切割)
        String[] single=num.split(",");
        //  作为 map 中的key                单选题   多选题  填空题   应用题
        String[] questionType=new String[]{"single","many","fill","application"};

        for (int i=0;i<4;i++){
            List<QuestionBase> List=questionDAO.randomQueryQuestion(Integer.parseInt(single[i]),i+1,chapter);
            map.put(questionType[i],List);
        }

        // 以用户账号为key ， 存储在缓存中 , 时间自定
        redisTemplate.opsForValue().set(username,map);
        return map;
    }


    /**
     *  查所有的科目
     * @return
     */
    @Cacheable(value = "subjects")
    public List<Map> subjects() {
        return questionDAO.subjects();
    }

    /**
     *  查所有的章节
     * @return
     */
    @Cacheable(value = "chapters")
    public List<Map> chapters() {
        return questionDAO.chapters();
    }

    /**
     *  查询试卷内容
     * @param username 用户账号
     * @param testId  试卷id
     * @return
     */
    public Map queryTest(String username, Integer testId) {
        // 在缓存中 根据用户账号作为 key , 找到存在redis中的数据
        Object object= redisTemplate.opsForValue().get(username);
        // 查到了,将数据取出,返回
        if(object!=null){
            Map map=(Map)redisTemplate.opsForValue().get(username);
            return map;
        }

        // 缓存中没有数据,从数据库中取出数据,以用户账号为key,存储在缓存中
       Map map=questionService.findByIdTest(testId);
        if(map!=null){
            // 根据试卷id 查询试卷内容
            Test test=testDAO.selectById(testId);
            // 以用户账号为key ， 存储在缓存中 , 时间为试卷中的规定考试时间
            redisTemplate.opsForValue().set(username,map,test.getTestTime(), TimeUnit.MINUTES);
            return map;
        }
        return null;
    }


    /**
     *  根据试卷id 查试卷内容
     * @param testId 试卷id
     * @return
     */
    public Map findByIdTest(Integer testId){
        Map map=new HashMap();
        // 根据试卷 id 查询试卷内容
        Test test=testDAO.selectById(testId);
        if(test==null){
            return null;
        }

        // 将试卷中不同试题类型的试题数量
        String[] questionType=new String[]{
                test.getSingleDifficulty(),
                test.getManyDifficulty(),
                test.getFillDifficulty(),
                test.getProgrammingDifficulty()
        };
        //  作为 map 中的key                单选题   多选题  填空题   应用题
        String[] questionTypeKey=new String[]{"single","many","fill","application"};
        // 查询不同试题类型的试题  1：单选题  2：多选题  3：问答题  4：应用题
        for(int i=0;i<4;i++){
            // 存储相同试题类型的试题
            List type=new ArrayList();
            //不同试题类型的题目数量( 以 / 切割) ，数据库存储格式 ( x/x/x )
            String[] difficulty=questionType[i].split("/");
            //试题难度  0：易  1：中  2：难
            for(int j=0;j<3;j++){
                // 条件查询试题  test.getChapterId：试卷科目章节id   i：试题类型   j：试题难度   difficulty[j]:试题数量
                List list=questionDAO.queryQuestion(test.getChapterId(),i+1,j,Integer.parseInt(difficulty[j]));
                // 将试题类型相同但试题难度不同的试题 存 type 集合中
                type.addAll(list);
            }
            // 将同类型的试题存储在 map 中
            map.put(questionTypeKey[i],type);
        }
        // 将试卷存 map 中
        map.put("test",test);
        return map;
    }


    /**
     * 删除redis缓存中的数据
     * @param username  缓存数据的key
     * @return
     */
    public boolean deleteTest(String username) {
        // 删除redis缓存中的数据
        redisTemplate.delete(username);
        Object object= redisTemplate.opsForValue().get(username);
        return object==null ? true : false;
    }

    /**
     *  查询考生的考题
     * @param rewindId   改卷id
     * @return
     */
    public Map findByIdRewind(Integer rewindId) {
        Map map=new HashMap();
        Rewind rewind=rewindDAO.selectById(rewindId);
        if(rewind==null){
            return null;
        }
        // 将试卷中不同试题类型的试题数量
        String[] questionType=new String[]{
                rewind.getSingleId(),
                rewind.getManyId(),
                rewind.getFillId(),
                rewind.getApplicationId()
        };
        //  作为 map 中的key                单选题   多选题  填空题   应用题
        String[] questionTypeKey=new String[]{"single","many","fill","application"};
        for(int i=0;i<4;i++) {
            // 存储相同试题类型的试题
            List type = new ArrayList();
            String[] question=questionType[i].split(",");
            for(int j=0;j<question.length;j++){
                QuestionBase questionBase=questionDAO.selectById(question[j]);
                type.add(questionBase);
            }
            map.put(questionTypeKey[i],type);
        }

        return map;
    }
}
